package com.grao.waterschool.human.manager.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.grao.waterschool.human.common.BusinessException;
import com.grao.waterschool.human.entiry.po.CourseDeviceInfo;
import com.grao.waterschool.human.entiry.vo.*;
import com.grao.waterschool.human.manager.service.ICCDeviceService;
import com.grao.waterschool.human.mapper.OdsPksjMapper;
import com.grao.waterschool.human.mapper.CourseDeviceInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.*;

import static com.grao.waterschool.human.manager.service.impl.ICCAuthorizeServiceImpl.refreshToken;

@Slf4j
@Service
public class ICCDeviceServiceImpl implements ICCDeviceService {

    //查询设备列表
    String getDeviceListURL = "https://10.0.25.224/evo-apigw/evo-brm/1.2.0/device/subsystem/page";

    @Autowired
    private RestTemplate restTemplate;

    private final RedisTemplate<String, String> redisTemplate;

    public ICCDeviceServiceImpl(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Autowired
    private OdsPksjMapper odsPksjMapper;

    @Autowired
    private CourseDeviceInfoMapper courseDeviceInfoMapper;

    @Autowired
    private ObjectMapper objectMapper;

    String[] BuildName = new String[]{"上德楼", "善思楼", "若谷楼", "水润楼", "海晏楼", "纳贤楼", "百湛楼", "川远楼"};

    private final Set<Integer> generatedIds = new HashSet<>();

    @Override
    @Transactional
    public List<Map<String, Object>> getDeviceList(Integer userId, SubSystemPage subSystemPage) throws Exception {
        String newToken = refreshToken(userId);
        log.info("提交数据：{}", subSystemPage);
        List<DeviceInfoVO> devicePage = getDevicePage(newToken, subSystemPage);

        List<Map<String, Object>> resultList = new ArrayList<>();

        for (DeviceInfoVO device : devicePage) {
            List<Map<String, Object>> channelInfoList = getChannelNamesAndCodes(device);
            resultList.addAll(channelInfoList);
        }
        saveChannelCodesToRedis(resultList);
        saveRoomInfo();
        return resultList;
    }

    //解析通道列表
    private List<Map<String, Object>> getChannelNamesAndCodes(DeviceInfoVO device) {
        List<Map<String, Object>> channelInfoList = new ArrayList<>();
        if (device.getUnits() != null) {
            for (UnitVO unit : device.getUnits()) {
                for (ChannelVO channel : unit.getChannels()) {
                    if (isBuildingNamePresent(channel.getChannelName()) && isValidChannelName(channel.getChannelName())) {
                        Map<String, Object> channelInfo = new HashMap<>();
                        String monitorThirdPart = channel.getChannelName().split("-")[2];
                        monitorThirdPart = processMonitorThirdPart(monitorThirdPart);
                        channelInfo.put("monitorThirdPart", monitorThirdPart);
                        channelInfo.put("channelName", channel.getChannelName());
                        channelInfo.put("channelCode", channel.getChannelCode());
                        channelInfoList.add(channelInfo);
                    }
                }
            }
        }

        return channelInfoList;
    }

//    public void saveChannelCodesToRedis(List<Map<String, Object>> channelInfoList) {
//        List<String> channelCodes = new ArrayList<>();
//        redisTemplate.delete("channelInfo");
//        for (Map<String, Object> channelInfo : channelInfoList) {
//            String channelCode = (String) channelInfo.get("channelCode");
//            channelCodes.add(channelCode);
//
//            // 使用 ObjectMapper 将 HashMap 转换为 JSON 字符串
//            try {
//                String channelInfoJson = objectMapper.writeValueAsString(channelInfo);
//                // 先将ChannelCode清空再存储
////                redisTemplate.opsForHash().delete("channelInfo");
//                redisTemplate.opsForHash().put("channelInfo", channelCode, channelInfoJson);
//
////                log.info("================channelCode================{}", channelCode);
//            } catch (JsonProcessingException e) {
////                log.error("将channelInfo序列化为JSON时出错", e);
//            }
//        }
//
//        // redis 里如果有旧的先删掉旧的再存入新的
//        if (Boolean.TRUE.equals(redisTemplate.hasKey("channelCode"))) {
//            redisTemplate.delete("channelCode");
//        }
//
//        // 将 channelCodes 列表存储到 Redis 中
//        redisTemplate.opsForList().leftPushAll("channelCode", channelCodes);
//    }

    public void saveChannelCodesToRedis(List<Map<String, Object>> channelInfoList) {
        List<String> channelCodes = new ArrayList<>();
        redisTemplate.delete("channelInfo");
        for (Map<String, Object> channelInfo : channelInfoList) {
            String channelCode = (String) channelInfo.get("channelCode");
            if (channelCode != null && !channelCode.isEmpty()) {
                channelCodes.add(channelCode);
                // 使用 ObjectMapper 将 HashMap 转换为 JSON 字符串
                try {
                    String channelInfoJson = objectMapper.writeValueAsString(channelInfo);
                    redisTemplate.opsForHash().put("channelInfo", channelCode, channelInfoJson);
                } catch (JsonProcessingException e) {
                    log.error("将channelInfo序列化为JSON时出错", e);
                }
            }
        }

        // 只有在 channelCodes 列表不为空时才执行 leftPushAll
        if (!channelCodes.isEmpty()) {
            redisTemplate.opsForList().leftPushAll("channelCode", channelCodes);
        } else {
            log.warn("没有通道代码可以推送到Redis，因为 channelCodes 列表为空");
        }
    }

    //确认所有的通道都是上善若水海纳百川
    private boolean isBuildingNamePresent(String channelName) {
        for (String buildingName : BuildName) {
            if (channelName.contains(buildingName)) {
                return true;
            }
        }
        return false;
    }

    //获取设备列表
    private List<DeviceInfoVO> getDevicePage(String token, SubSystemPage subSystemPage) throws IOException {
        String jsonRequestBody = objectMapper.writeValueAsString(subSystemPage);
//        log.info("发送数据：{}", jsonRequestBody);
        HttpEntity<String> requestEntity = new HttpEntity<>(jsonRequestBody, getHeaders(token));
        ResponseEntity<String> responseEntity = restTemplate.exchange(getDeviceListURL, HttpMethod.POST, requestEntity, String.class);
//        log.info("返回数据：{}", responseEntity);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            String responseBody = responseEntity.getBody();
            if (responseBody != null) {
                try {
                    DeviceResponse deviceResponse = objectMapper.readValue(responseBody, DeviceResponse.class);
                    if (deviceResponse.isSuccess()) {
//                        log.info("设备列表: {}", deviceResponse.getData().getPageData());
                        return deviceResponse.getData().getPageData();
                    } else {
                        throw new RuntimeException("请求失败: " + deviceResponse.getErrMsg());
                    }
                } catch (Exception e) {
                    throw new RuntimeException("解析响应失败", e);
                }
            }
        }
        throw new RuntimeException("请求失败或返回数据为空");
    }

    static HttpHeaders getHeaders(String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("Accept", "*/*");
        headers.add("Authorization", "bearer " + token);
//        log.info("headers:{}", headers);
        return headers;
    }

    //筛选所有的教室通道
    private boolean isValidChannelName(String channelName) {
        String regex = "^.*-.*-(\\d+.*\\s*(?:前|前\\(西\\)|西))$";
        return channelName.matches(regex);
    }

    // 处理 monitorThirdPart
    private String processMonitorThirdPart(String monitorThirdPart) {
        monitorThirdPart = monitorThirdPart.replaceAll("前\\(西\\)|前|西", "").trim();
/*        if (!monitorThirdPart.startsWith("10") && monitorThirdPart.length() > 5) {
            monitorThirdPart = monitorThirdPart.substring(1);
        }
        if (monitorThirdPart.matches("\\d{3}")) {
            monitorThirdPart = "10" + monitorThirdPart;
        }*/
        return monitorThirdPart;
    }

    private int generateRandomId() {
        int id;
        do {
            id = (int) (Math.random() * 900000000) + 100000000;
        } while (generatedIds.contains(id));
        generatedIds.add(id);
        return id;
    }

    // 获取教室信息并存入数据库
/*    @Transactional
    public void saveRoomInfo() {
        List<CourseListInfo> courseListInfos = odsPksjMapper.selectCourseList(null);
        List<Object> channelInfos = redisTemplate.opsForHash().values("channelInfo");
        List<CourseDeviceInfo> courseDeviceInfos = new ArrayList<>();
        List<Map<String, Object>> unmatchedChannels = new ArrayList<>();

        // 使用 Set 存储已处理的教室号
        Set<String> processedClassroomSet = new HashSet<>();
        Map<String, String> processedClassroomMap = new HashMap<>();

        // 提前构建教室号到 CourseListInfo 的映射
        Map<String, CourseListInfo> courseListMap = new HashMap<>();
        for (CourseListInfo courseListInfo : courseListInfos) {
            String originalJsh = courseListInfo.getJsh();
            if (!processedClassroomSet.contains(originalJsh)) {
                String processedJsh = processClassroomNumber(originalJsh);
                processedClassroomSet.add(originalJsh);
                processedClassroomMap.put(originalJsh, processedJsh);
            }
            courseListMap.put(processedClassroomMap.get(originalJsh), courseListInfo);
        }

        for (Object obj : channelInfos) {
            JSONObject jsonObject = JSONObject.parseObject(obj.toString());
            String monitorThirdPart = (String) jsonObject.get("monitorThirdPart");
            boolean matched = false;

            // 检查匹配
            if (courseListMap.containsKey(monitorThirdPart)) {
                matched = true;
                CourseListInfo courseListInfo = courseListMap.get(monitorThirdPart);
                CourseDeviceInfo courseDeviceInfo = CourseDeviceInfo.getInstance(courseListInfo)
                        .setId(generateRandomId())
                        .setJkh(monitorThirdPart)
                        .setChannelName((String) jsonObject.get("channelName"))
                        .setChannelCode((String) jsonObject.get("channelCode"));
                courseDeviceInfos.add(courseDeviceInfo);
                log.info("教室信息: {}", courseDeviceInfos);
            } else {
                unmatchedChannels.add(jsonObject);
            }
        }

        try {
            if (!courseDeviceInfos.isEmpty()) {
                courseDeviceInfoMapper.insert(courseDeviceInfos);
            } else {
                throw new BusinessException("courseDeviceInfos为空！！！！！！！！");
            }
        } catch (Exception e) {
            log.error("批量插入 CourseDeviceInfo 时出错: ", e);
        }
    }*/

    @Transactional
    public void saveRoomInfo() {
        List<CourseListInfo> courseListInfos = odsPksjMapper.selectCourseList(null);
        List<Object> channelInfos = redisTemplate.opsForHash().values("channelInfo");
        List<CourseDeviceInfo> courseDeviceInfos = new ArrayList<>();

        // 提前构建教室号到 CourseListInfo 的映射
        Map<String, JSONObject> courseListMap = new HashMap<>();
        for (Object obj : channelInfos) {
            JSONObject jsonObject = JSONObject.parseObject(obj.toString());
            String monitorThirdPart = (String) jsonObject.get("monitorThirdPart");
            courseListMap.put(monitorThirdPart, jsonObject);
        }

        for (CourseListInfo courseListInfo : courseListInfos) {
            if (courseListMap.containsKey(courseListInfo.getJsh())) {
                JSONObject jsonObject = courseListMap.get(courseListInfo.getJsh());
                String monitorThirdPart = (String) jsonObject.get("monitorThirdPart");
                CourseDeviceInfo courseDeviceInfo = CourseDeviceInfo.getInstance(courseListInfo)
                        .setId(generateRandomId())
                        .setJkh(monitorThirdPart)
                        .setChannelName((String) jsonObject.get("channelName"))
                        .setChannelCode((String) jsonObject.get("channelCode"));
                courseDeviceInfos.add(courseDeviceInfo);
            }
        }


        try {
            if (!courseDeviceInfos.isEmpty()) {
                List<List<CourseDeviceInfo>> list = new ArrayList<>();
                if(courseDeviceInfos.size() > 1000){
                    int size = courseDeviceInfos.size() / 1000;
                    if(courseDeviceInfos.size() % 1000 > 0){
                        size += 1;
                    }
                    int start = 0;
                    int end = 1000;
                    for (int i = 0; i < size; i++){
                        start = i * 1000;
                        end = start + 1000;
                        if(i == size - 1){
                            List<CourseDeviceInfo> courseDeviceInfoList = courseDeviceInfos.subList(start, courseDeviceInfos.size());
                            list.add(courseDeviceInfoList);
                        } else {
                            List<CourseDeviceInfo> courseDeviceInfoList = courseDeviceInfos.subList(start, end);
                            list.add(courseDeviceInfoList);
                        }
                    }
                }
                for (List<CourseDeviceInfo> courseDeviceInfoList : list){
                    log.info("教室信息: {}", courseDeviceInfoList);
                    courseDeviceInfoMapper.insert(courseDeviceInfoList);
                }
            } else {
                throw new BusinessException("courseDeviceInfos为空！！！！！！！！");
            }
        } catch (Exception e) {
            log.error("批量插入 CourseDeviceInfo 时出错: ", e);
        }
    }

    public String processClassroomNumber(String classroomNumber) {
//        log.info("原始教室号: {}", classroomNumber);

        // 5位数字，去掉第一位
        if (classroomNumber.length() == 5) {
            classroomNumber = classroomNumber.substring(1);
        }
        // 6位数字，且第一位是 '1'，去掉第一位
        else if (classroomNumber.length() == 6 && classroomNumber.startsWith("1")) {
            classroomNumber = classroomNumber.substring(1);
        }
        // 5位数字加1位汉字，去掉第一位数字和汉字
        else if (classroomNumber.length() == 6 && isChineseCharacter(classroomNumber.charAt(5))) {
            classroomNumber = classroomNumber.substring(1, 5); // 去掉第一个数字
        }

        // 如果最后一位是汉字，去掉汉字
        if (classroomNumber.length() > 0 && isChineseCharacter(classroomNumber.charAt(classroomNumber.length() - 1))) {
            classroomNumber = classroomNumber.substring(0, classroomNumber.length() - 1);
        }

        // 打印处理后的教室号
        log.info("处理后的教室号: {}", classroomNumber);

        return classroomNumber;
    }

    public boolean isChineseCharacter(char ch) {
        // 判断字符是否在汉字的 Unicode 范围内
        return ch >= 0x4E00 && ch <= 0x9FFF;
    }
}
